import { Injectable } from '@nestjs/common';
import * as bcrypt from 'bcrypt';
import { JwtService } from '@nestjs/jwt';
import { User } from '@/modules/users/entities/user.entity';
import { ConfigService } from '@/common/config/config.service';
import { UserRegisterDto } from '../dto/user-register.dto';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';

@Injectable()
export class AuthService {
  constructor(
    @InjectRepository(User) private readonly userRepo: Repository<User>,
    private readonly jwtService: JwtService,
    private readonly config: ConfigService,
  ) {}

  /**
   * 验证用户登录凭据
   * @param name 登录名称：用户名/手机号（中国大陆）/邮箱
   * @param pwd 密码
   */
  async validateUser(name: string, pwd: string): Promise<User> {
    const em = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    const ph = /^1[345678]\d{9}$/; // 中国大陆手机号
    let user: User;
    if (em.test(name)) {
      // 电子邮箱登录
      user = await this.userRepo.findOne({ email: name });
    } else if (ph.test(name)) {
      // 手机号登录
      user = await this.userRepo.findOne({ phone: name });
    } else {
      // 用户名登录
      user = await this.userRepo.findOne({ username: name });
    }

    if (user && (await bcrypt.compare(pwd, user.password))) {
      return user;
    }
    return null;
  }

  async login(user: User) {
    const payload = {
      sub: user.id.toString(),
    };
    return {
      accessToken: await this.jwtService.signAsync(payload, {
        expiresIn: this.config.authTokenExpiresIn,
      }),
    };
  }

  async logout(user: User) {
    // TODO
    return true;
  }

  async register(userRegisterDto: UserRegisterDto) {
    const newUser = this.userRepo.create(userRegisterDto);
    const { password, ...res } = await this.userRepo.save(newUser);
    return res;
  }

  async getUser(id: number) {
    const { password, ...user } = await this.userRepo.findOneOrFail(id);
    return user;
  }
}
